/*
* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. 
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "ai_inference.h"
#include "utils/log/infer_log.h"
#include "ai_retcode.h"
#include "utils/infer_guard.h"
#include "ai_datatype.h"
#include "protocol/retcode_inner/infer_retcode_inner.h"
//#include "utils/encdec/include/encdec_facade.h"
#include "include/i_infer_client.inl"



namespace OHOS {
namespace AI_STD {
int32_t AiInference::Create(int frameworkType, const std::string &algorithmName, std::vector<ModelPathInfo> &modelPathInfos, 
                            long long algorithmVersion)
{
    if (frameworkType >= AI_FRAMEWORK_ID_COUNT || frameworkType <= AI_FRAMEWORK_ID_INVALID) {
        HILOGE("[AIINFERENCE][frameworkType:[%d] is invalid", frameworkType);
        return AI_RETCODE_FAILURE;
    }

    algorithmInfo_.frameworkType = frameworkType;
    algorithmInfo_.algorithmName = algorithmName;
    algorithmInfo_.algorithmVersion = algorithmVersion;
    algorithmInfo_.modelPathInfos = modelPathInfos;
 

    int32_t retCode = ClientInit(configInfo_, clientInfo_, algorithmInfo_, nullptr);
    if (retCode != RETCODE_SUCCESS) {
        HILOGE("[AiInferenceImpl]ClientInit failed. Error code[%d]", retCode);
        return AI_RETCODE_INIT_ERROR;
    }
    if (clientInfo_.clientId == INVALID_CLIENT_ID) {
        HILOGE("[AiInferenceImpl]Fail to allocate client id");
        return AI_RETCODE_INIT_ERROR;
    }
    DataInfo inputInfo;
    DataInfo outputInfo;
    retCode = ClientPrepare(clientInfo_, algorithmInfo_, inputInfo, outputInfo, nullptr);
    if (retCode != RETCODE_SUCCESS) {
        (callback_ != nullptr) ? (callback_->OnError(AI_RETCODE_INIT_ERROR))
                               : HILOGD("[AiInferenceImpl]No callback");
        HILOGE("[AiInferenceImpl]ClientPrepare failed. Error code[%d]", retCode);
        return AI_RETCODE_INIT_ERROR;
    }

    return AI_RETCODE_SUCCESS;
}



int32_t AiInference::SyncExecute(const IOTensors &inputInfo, IOTensors &outputInfo)
{
    HILOGI("[AiInferenceImpl]Start");
    if (inputInfo.size() == 0) {
        HILOGE("[AiInferenceImpl]Empty input");
        return AI_RETCODE_NULL_PARAM;
    }

    int32_t retCode = ClientSyncProcess(clientInfo_, algorithmInfo_, inputInfo, outputInfo);
    if (retCode != RETCODE_SUCCESS) {
        HILOGE("[AiInference]ClientSyncProcess failed. Error code[%d]", retCode);
        (callback_ != nullptr) ? (callback_->OnError(AI_RETCODE_PLUGIN_EXECUTION_ERROR))
                                   : HILOGD("[AiInference]No callback");
        return AI_RETCODE_PLUGIN_EXECUTION_ERROR;
    }
    if (outputInfo.size() == 0) {
        HILOGE("[AiInference]The data or length of output info is invalid. Error code[%d]", retCode);
        (callback_ != nullptr) ? (callback_->OnError(AI_RETCODE_NULL_PARAM))
                                   : HILOGD("[AiInference]No callback");
        return AI_RETCODE_NULL_PARAM;
    }

    if (callback_ != nullptr) {
        callback_->OnResult(static_cast<IOTensors>(outputInfo));
    } 
    
    return AI_RETCODE_SUCCESS;
}

int32_t AiInference::SetCallback(const std::shared_ptr<ICallback> &callback)
{
    if (callback == nullptr) {
        return AI_RETCODE_NULL_PARAM;
    }
    callback_ = callback;
    return AI_RETCODE_SUCCESS;
}

int32_t AiInference::Destroy()
{
    HILOGI("[AiInferenceImpl]Destroy");
    DataInfo inputInfo;
    int32_t retCode = ClientRelease(clientInfo_, algorithmInfo_, inputInfo);
    if (retCode != RETCODE_SUCCESS) {
        (callback_ != nullptr) ? (callback_->OnError(AI_RETCODE_FAILURE))
                               : HILOGD("[AiInferenceImpl]No callback");
        HILOGE("[AiInferenceImpl]ClientRelease failed. Error code[%d]", retCode);
        return AI_RETCODE_FAILURE;
    }
    
    retCode = ClientDestroy(clientInfo_);
    if (retCode != RETCODE_SUCCESS) {
        (callback_ != nullptr) ? (callback_->OnError(AI_RETCODE_FAILURE))
                               : HILOGD("[AiInferenceImpl]No callback");
        HILOGE("[AiInferenceImpl]ClientDestroy failed. Error code[%d]", retCode);
        return AI_RETCODE_FAILURE;
    }
    return AI_RETCODE_SUCCESS;
}
} // namespace AI_STD
} // namespace OHOS
